回顾·携程HBase实践
本文由DataFun社区根据携程魏宁、颜志远俩位老师在中国HBase技术社区第四届MeetUp上海站中分享的《携程HBase实践》编辑整理而成。
今天分享的内容主要是携程在HBase使用上的一些概况、场景以及在监控、客户端、版本迁移/升级方面的一些工作,此外还有日常工作中的几个问题和案例。
一、概况
目前我们使用的HBase版本为1.2.0-cdh5.7.1版,表的数量1000张以上,大表超过了100TB。白天QPS请求在5百万上下,在促销或者旅游旺季更大,每天写入HDFS数据量在50TB左右。主要场景有用户行为数据采集(用户的点击、浏览等信息都在HBase上提供给后方用户画像使用),还有风控,用户产生的每一笔订单和交易都会触发一些风控规则的校验。还有就是自研类OpenTSDB,将埋点数据分析给应用,查看应用请求量和延迟等信息。还有就是广告,主要用途是提供精准营销、千人千面的广告展示。
以广告为例,我们来看一下HBase的应用。数据来源主要有网站的业务系统、各个BU以及来自站外合作伙伴的数据,首先数据先进入Hermes消息队列里面,通过Jstorm job写入到HBase。当用户浏览网站或者使用APP或有广告投放站点时就会触发广告服务,根据用户标签或用户id等从HBase查询内容返回给用户,由于HBase查询是根据用户的每次点击实时查询的,因此对于一些响应的延迟是非常敏感的,采用SSD技术缓解延迟,目前集群访问延迟基本控制在10ms以内。
除了以上场景外,其他所有业务线都用到了HBase。使用方式基本类似,实时写一般通过Jstorm/HBaseAPI写入HBase,批量写一般通过SPARK/MR/Hive/Kylin等,应用读取HBase再去使用。
二、监控
大致思路是首先采集数据,包括来自hickwall监控平台的OS性能数据、来自jmx或者API采集的HBase性能数据和HDFS性能数据以及来自zookeeper的其它数据。数据落地到inflexDB,然后在Griffin上展示,同时依据一些规则产生一些告警。
下图列出了一些常用指标如连接数、响应时间和处理时间,通过请求数判断业务情况。有读请求、写请求以及总请求,跟性能有关的请求大小。一般监控比较感兴趣的是flash队列、Compaction队列,flash队列请求比较大意味着机群的写负载比较重,如果高峰期Compaction队列有积压需要调整Compaction策略,避免业务高峰期影响性能。Blockcache命中率对读写性能影响比较大,如果读的时候不能在缓存中命中就需要在磁盘中读取,这样读写延迟比较高。Hlog、Storefile文件数过大,则表明写的负载比较重,也会根据Storefile文件大小,如Regionserver上总Storefile文件大小预估Major Compaction的消耗。Major Compaction将所有数据读出来写成一个新的文件,如果Storefile很大,预示着Compaction消耗也很大。
有可能我们除了读请求之外,还可能想关注Get次数和Scan的次数,在了解了是写请求之外,还有可能想了解put次数。接下来还有GC的次数与GC的耗时,如果GC的频率很高,耗时也很长的话,那往往意味着集群可能存在着一些问题,就需要具体分析。除了这些官方的指标之外,我们通过修改源代码,新加了一些指标,具体指标如下图所示。
我们有一个需求:希望从用户角度去感知集群的健康状况,所以开发了模仿用户检测异常的功能,其思路是建一个表,建表的时候首先会知道集群有多少RegionServer,根据RegionServer数量进行预分区,构建Region;检查确保每个RegionServer上都有Region;然后每个一段时间对所有RegionServer 进行put/scan一行,分别获取耗时。这样得到一个直观的数据可以了解到用户的访问延迟或者哪个RegionServer的响应延迟比较大,可以方便排障,而且在读写的时候,如果产生了错误,我们也可以集成一些报警规则,比如连续失败N次需要报警灯等。
我们平常工作中常用如下图所示的看板,展示了所有的HBase集群服务器的一些关键性指标,每个指标下面有个状态灯,如果是绿色的,表示服务器指标处于一个健康的状态,用红色表示需要马上处理的状态,黄色可能需要我们关注一下,我们会将红色与黄色的呈现在最上端,以便更容易发现与及时处理。这些指示灯按钮可以点击来查看监测数据,例如打开Ping指示灯可以看最近一段时间Ping是否失败与时长,Disk可以查看硬盘容量的使用情况,CPU点开可以展示最近CPU使用率的变化,SWAP展示有没有使用SWAP以及使用率,QPS表示请求量,NetWork展示最近每块网卡的流量使用情况,IO指IO延迟。
除此之外,我们还从几个维度提供了几个不同的看板,比如说下图所示的第一个是“集群概览”看板,展示了集群总的请求量,以及某些指标MaxTopN的RegionServer,比如说想知道有哪些RegionServer的请求量是最高的,可以通过MaxTopN指标展示哪些RegionServer比较高,还有它们的延迟或者各种队列情况。总之,我们希望通过看板能比较容易地大概了解集群的整体情况。
第二是“服务器”,这里展示的是一个集群下面所有服务器的指标,看板的主要作用是可以通过它能够快速地知道这个集群中有哪个服务器请求量特别大,或者它有什么性能异常,能够快速发现问题服务器。
下图一展示的是“表”看板,这里展示的是这个表在集群所有RegionServer上的请求量,它的作用是让我们快速发现表有没有热点或者热点是在哪个RegionServer上。有时候我们需要从InfluxDB上根据自己需要自定义查询,如下图二所示“自定义查询”,比如想查询集群中请求量最大的表有哪些或者整个集群中最热的Region是哪个,可以通过自定义查询。以上这几个功能基本可以完成日常运维的需要。
三、Client
客户端方面,我们根据自己的需求作了一些调整工作,首先主要的改变就是接入携程的整个框架中,比如说接入统一日志收集平台、统一Bom文件、流量控制等。由于HBase对Guava依赖的是11版,而很多用户使用的第三方产品可能依赖的是18版,那么就会产生版本的冲突,我们可以通过Shade Guava来解决冲突问题。针对流量控制,我们做了一些规则,当服务器比较繁忙的时候响应会超时,我们根据一定域值直接返回给当前用户当前很忙,需要等待一段时间的信息,主要目的是防止在服务器负载很重的情况下,用户又不断请求,造成服务器恶化。
我们也接入了携程的配置中心,通过客户端快速获取集群的连接配置,主要作用是动态切换集群。比如客户端想从A集群的访问切换到B集群,只需要在QConfig中配置信息改成B集群,那么客户端在新建连接的时候就能感知到配置信息发生了变化,这时候就会关闭A集群上的Connection和Table,然后new Connection到B集群上,此时可能A集群原有的连接会有短暂的报错。
此外我们在客户端加了埋点信息,用户可以把这些访问的一些统计信息加到DashBoard上,比如说用户请求量、每次请求的延迟情况、每次请求延迟大小。通过下图这个产品我们可以方便地告诉用户应用响应慢是因为用户逻辑慢还是由于HBase响应慢。
四、迁移/升级
下面分享一下日常跨地区迁移或者版本迁移升级用的一些方法。目前同版本迁移可用的工具有很多,首先介绍一下离线迁移的概念。
离线迁移指的是为了迁移前后数据的一致性,在迁移前希望用户能够停止写入,迁移完成后用户可以把写入直接集成到新的集群上,这种操作方式我们称为离线迁移。第一种是直接在Hive上操作,把A集群的数据先加入到Hive,然后再写入B集群,从而完成迁移;平时用的较多的是Export/Import,其优点是可以使用增量迁移,在迁移时可以指定时间戳;迁移较快的是直接Copy HFile,然后在新集群直接BulkLoad,因为它跳过了HBase层面的一些交互,速度非常快;偶尔我们也会用Copytable,因为与其他工具相比,它比较简单。
在线迁移是指在不停止读写应用的前提下完成迁移,我们采用了两种方法:第一种是通过Replication,首先在新旧集群之间复制表,将新数据同步到新集群中,再用Export/Import工具把旧的数据导入到新集群;第二种是直接在应用端修改,直接双写,将数据同时写入新旧集群,在开始写之后,再把旧集群的数据往新集群导一遍,导完之后切换应用。
还有升级问题,如果采用原地升级,可能需要停机,而且步骤比较繁琐,可能需要先升级HDFS,然后升级HBase,等等,我们基本不采用这种方式。我们采用的升级基本是先搭建一个新的1.2的集群,然后在Hive上操作,把HBase0.94上的数据先读到Hive,然后再写入到1.2的集群,为了确保迁移前后数据的一致性,我们在迁移过程中要求用户停止写入。我们还可以通过修改Replication,通过模拟Replication来完成迁移。
如下图所示,首先我们了解一下Replication的流程,当搭建好Replication以后,客户端往Master集群写入数据的时候,先写入hlog,然后有一个Standby的RPL线程读入日志并解析数据,然后将数据写入到Slave集群。
我们修改了往Slave集群写入的步骤,如下图所示,将解析出来的数据先加入到KAFKA,再用Jstrom消费写入新的集群中。采用这种方式来完成迁移。
五、日常
接下来分享一下日常中的一些常见问题的处理和几个案例。
1.如果在业务高峰期进行大表MajorCompaction,对性能影响比较大,会影响应用的访问,那么如何处理呢?
首先修改配置信息,限制Compaction的带宽,然后关闭自动的Compaction,然后通过脚本以Region为单位进行MajorCompaction,周期为N天,周期根据lastMajorCompactionTimestamp、TTL、writes判断。
2.大表避免Split风暴问题
当表很大,Region非常多的时候,如果数据分布比较均匀,可能会同时触发Split,在业务高峰期触发Split,对性能损耗非常大。
最好的办法是在进行表设计的时候进行预分区,评估一下数据量,做好分区方法。在很多时候,可能表已存在,那么如何避免呢?我们通过获取Client设置不当报错以及其他热点问题。举例说明,在实际工作中遇到某个Client一直报错RegionMovedException的问题。Region迁移了报错,但为什么平时没有遇到这种问题呢?我们通过在业务低峰期提前Split的方式,避免业务高峰期自己Split。
3.大家关心的还有访问的热点问题,这个主要确保rowkey设计不存在热点,当Region比较小时,实现自动化Split过热的Region。
4.常见错误排障的分享。
比如某个Client一直报错RegionMovedException?很多时候是因为Region 迁移了报错。当发生错误后我们开始查找问题,如下图所示,当hbase.client.retries.number<=1出现这种错误时直接throwable,没有重试机会,或者当hbase.client.operation.timeout非常低时出现错误直接throwable,没有重试机会。
5.一次IO问题
有时候应用突然响应变慢,后续自动恢复,过段时间可能还有缓慢,如下图所示。
我们通过查看性能,发现有一个RegionServer在这个时间点CPU有冲高,然后我们也发现它的CPU_wio也有冲高,此时基本可以定位到IO问题导致的。我们通过HBase的错误日志,发现访问HDFS超时,然后查看datanode的日志信息也可以发现写入耗时非常大,然后查看一些批处理的日志消息,发现磁盘的一些异常信息,发现磁盘的访问延迟大。最后通过如下命令查看SMART信息:sudo smartctl -A /dev/sdf ,第一天看到VALUE值为90多(低于100就有问题),正常值应该是100。第二天再次运行:直接报检测失败,值降低到15。至此可以确认是sdf磁盘坏掉了。
六、总结
前面报告主要介绍了HBase在携程的一些应用。包括业务应用,监控告警,client封装,迁移升级和遇到的一些问题。以后会调研下Hbase2.0一些新特性并在高可用方面做些尝试。
作者介绍:
魏宁,携程大数据高级工程师,主要负责 HBase、presto、kylin,热衷于大数据开源技术;
颜志远,携程高级DBA,专注于HBase的开发运维,热衷于mysql、redis、HBase等数据库技术。
关注本公众号,后台回复“携程HBase”可下载PPT原文。
——END——
内推信息:
大数据系统开发工程师:1、负责携程大数据系统平台开发与管理2、负责大数据开发和查询平台建设,包括数据传输,调度,主数据,质量中心以及报表和Adhoc查询系统等;3、助力携程数据化运营业务,构建丰富多样的大数据应用,Base上海,想看机会的小伙伴,欢迎加入携程魏宁老师团队,内推邮箱:nwei@ctrip.com。
文章没看够?下面还有: